/**
 * Copyright (C) 2009 aileron.cc
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package cc.aileron.wsgi.extension;

import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.nio.charset.Charset;
import java.util.EnumMap;

import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cc.aileron.accessor.PojoAccessorFactory;
import cc.aileron.commons.resource.ResourceNotFoundException;
import cc.aileron.commons.utils.ResourceUtils;
import cc.aileron.template.Template;
import cc.aileron.template.TemplateCategory;
import cc.aileron.template.TemplateCompiler;
import cc.aileron.template.parser.ParserMethodNotFoundException;
import cc.aileron.template.reader.TemplateSyntaxEexception;
import cc.aileron.wsgi.activity.WsgiActivity;
import cc.aileron.wsgi.activity.WsgiProcess;
import cc.aileron.wsgi.init.WsgiEnvironment;

import com.google.inject.Inject;

/**
 * @author Aileron
 */
public class TemplateProcessProviderDevelopment implements
    TemplateProcessProvider
{
    @Override
    public <Resource> WsgiProcess<Resource> get(final String path) throws TemplateSyntaxEexception,
            ParserMethodNotFoundException,
            ResourceNotFoundException
    {
        return get(path, TemplateCategory.XML);
    }

    @Override
    public <Resource> WsgiProcess<Resource> get(final String path,
            final String contentType) throws TemplateSyntaxEexception,
            ParserMethodNotFoundException,
            ResourceNotFoundException
    {
        final TemplateCompiler templateCompiler = compilerMap.get(TemplateCategory.XML);
        final PojoAccessorFactory accessor = this.accessorFactory;
        final Charset encode = environment.getEncode();
        return new WsgiProcess<Resource>()
        {
            @Override
            public void doProcess(final WsgiActivity<Resource> activity) throws Exception
            {
                final String resouce = ResourceUtils.resource(path)
                    .toString();

                final Template template = templateCompiler.compile(resouce);
                final HttpServletResponse response = activity.context()
                    .response();

                response.setContentType(contentType);
                response.setHeader("Pragma", "no-cache");
                response.setHeader("Cache-Control", "no-cache");
                response.setDateHeader("Expires", 0);

                final PrintWriter writer = new PrintWriter(
                        new OutputStreamWriter(response.getOutputStream(),
                                encode));
                template.print(accessor.create(activity), writer);
            }

            @Override
            public String toString()
            {
                return this.getClass() + " : " + path;
            }
        };
    }

    /*
     * (非 Javadoc)
     * 
     * @see
     * cc.aileron.wsgi.extension.TemplateProcessProvider#get(java.lang.String,
     * cc.aileron.template.TemplateCategory)
     */
    public <Resource> WsgiProcess<Resource> get(final String path,
            final TemplateCategory category) throws TemplateSyntaxEexception,
            ParserMethodNotFoundException,
            ResourceNotFoundException
    {
        final TemplateCompiler templateCompiler = compilerMap.get(category);
        final PojoAccessorFactory accessor = this.accessorFactory;
        return new WsgiProcess<Resource>()
        {
            @Override
            public void doProcess(final WsgiActivity<Resource> activity) throws Exception
            {
                final String resouce = ResourceUtils.resource(path)
                    .toString();

                final Template template = templateCompiler.compile(resouce);
                final HttpServletResponse response = activity.context()
                    .response();

                response.setContentType("text/html");
                response.setHeader("Pragma", "no-cache");
                response.setHeader("Cache-Control", "no-cache");
                response.setDateHeader("Expires", 0);

                final PrintWriter writer = response.getWriter();
                template.print(accessor.create(activity), writer);
            }

            @Override
            public String toString()
            {
                return this.getClass() + " : " + path;
            }
        };
    }

    /**
     * constractor injection
     * 
     * @param compilerMap
     * @param accessorFactory
     * @param environment
     * 
     */
    @Inject
    public TemplateProcessProviderDevelopment(
        final EnumMap<TemplateCategory, TemplateCompiler> compilerMap,
        final PojoAccessorFactory accessorFactory,
        final WsgiEnvironment environment)
    {
        this.compilerMap = compilerMap;
        this.accessorFactory = accessorFactory;
        this.environment = environment;
    }

    private final WsgiEnvironment environment;

    /**
     * logger
     */
    final Logger logger = LoggerFactory.getLogger(this.getClass());

    private final PojoAccessorFactory accessorFactory;

    private final EnumMap<TemplateCategory, TemplateCompiler> compilerMap;

}
